#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/mount.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include "main.h"
static char data[] = {"0123456789"};
static int data_index = 0;
static ssize_t my_read(struct file *f, char __user *buf, size_t count, loff_t *f_pos)
{
    printk(KERN_INFO "my_read\n");
    if (data_index > 9)
    {
        data_index = 0;
        return 0;
    }
    count = (10 - data_index) >= count ? count : 10 - data_index;
    if (copy_to_user(buf, data, count))
    {
        return -EFAULT;
    };
    data_index += count;
    (*f_pos) += count;
    return count;
};
static ssize_t my_write(struct file *f, const char __user *buf, size_t count, loff_t *f_pos)
{
    printk(KERN_INFO "my_write\n");
    (*f_pos) += count;
    return count;
};
static int my_open(struct inode *i, struct file *f)
{
    printk(KERN_INFO "file open\n");
    return 0;
};
static int my_release(struct inode *i, struct file *f)
{
    printk(KERN_INFO "file close\n");
    return 0;
};

static void init_my_operations()
{
    my_inode_operations = simple_dir_inode_operations;
    my_inode_operations.create = my_create;
    my_inode_operations.mkdir = my_mkdir;
    my_inode_operations.link = simple_link;
    my_inode_operations.unlink = simple_unlink;
    my_inode_operations.rmdir = simple_rmdir;
}
static int my_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool b)
{
    printk(KERN_INFO "in my_create\n");
    printk(KERN_INFO "%s\n", dentry->d_iname);
    struct inode *inode = new_inode(dir->i_sb);
    inode->i_ino = get_next_ino(); // 获取唯一的inode编号
    inode_init_owner(&nop_mnt_idmap, inode, dir, mode | S_IFREG);
    inode->i_op = &my_inode_operations;
    inode->i_fop = &my_file_ops;
    d_instantiate(dentry, inode);
    dget(dentry);
    return 0;
};

static int my_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode)
{
    printk(KERN_INFO "in my_mkdir\n");
    printk(KERN_INFO "%s\n", dentry->d_iname);
    struct inode *inode = new_inode(dir->i_sb);
    inode_init_owner(&nop_mnt_idmap, inode, dir, mode | S_IFDIR);
    set_nlink(inode, 2);           // 初始链接数：2（.和自身）
    inode->i_ino = get_next_ino(); // 获取唯一的inode编号
    inode->i_op = &my_inode_operations;
    inode->i_fop = &my_dir_ops;
    d_instantiate(dentry, inode);
    inc_nlink(dir);
    dget(dentry);
    // inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
    return 0;
};

static struct inode *myfs_get_inode(struct super_block *sb, const struct inode *dir, int mode, dev_t dev)
{

    struct inode *inode = new_inode(sb); // 创建新的inode
    if (!inode)
        return NULL;
    inode->i_ino = get_next_ino(); // 获取唯一的inode编号
    inode_init_owner(&nop_mnt_idmap, inode, dir, mode);

    inode->i_op = &my_inode_operations; // 设置inode操作
    inode->i_fop = &my_dir_ops;         // 设置目录操作

    return inode;
}

// 填充超级块信息
static int myfs_fill_super(struct super_block *sb, void *data, int silent)
{
    sb->s_magic = 0x12345678;   // 设置文件系统的魔数
    sb->s_op = &myfs_super_ops; // 设置超级块操作
    sb->s_fs_info = NULL;       // 没有额外的文件系统信息

    // 创建根目录inode，并将其设置为超级块的根目录
    struct inode *root_inode = myfs_get_inode(sb, NULL, S_IFDIR | 0755, 0);
    if (!root_inode)
    {
        printk(KERN_INFO "root_inode failed\n");
        return -ENOMEM; // 内存分配失败
    }

    sb->s_root = d_make_root(root_inode); // 创建根目录的dentry
    if (!sb->s_root)
    {
        iput(root_inode); // 如果创建失败，释放root_inode
        printk(KERN_INFO "sb->s_root failed\n");
        return -ENOMEM;
    }
    printk(KERN_INFO "myfs_fill_super 0\n");
    return 0;
}

// 挂载文件系统
static struct dentry *myfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data)
{
    init_my_operations();
    return mount_nodev(fs_type, flags, data, myfs_fill_super); // 使用无设备挂载
}
// 卸载文件系统时的操作
static void myfs_kill_super(struct super_block *sb)
{
    pr_info("myfs: superblock is being killed\n");
}

// 文件系统类型定义
static struct file_system_type myfs_type = {
    .name = "myfs",             // 文件系统名称
    .mount = myfs_mount,        // 挂载函数
    .kill_sb = myfs_kill_super, // 卸载函数
    .owner = THIS_MODULE,       // 模块所有者
};

// 初始化文件系统模块
static int __init myfs_init(void)
{
    printk(KERN_INFO "init start \n");
    int ret = register_filesystem(&myfs_type); // 注册文件系统
    if (ret)
        printk(KERN_ERR "myfs: unable to register myfs %d\n", ret);
    else
        printk(KERN_INFO "myfs: myfs registered %d\n", ret);

    return ret;
}

// 清理文件系统模块
static void __exit myfs_exit(void)
{
    unregister_filesystem(&myfs_type); // 卸载文件系统
    printk(KERN_INFO "myfs: myfs unregistered\n");
}

// 模块入口和出口
module_init(myfs_init);
module_exit(myfs_exit);

// 模块信息
MODULE_LICENSE("GPL");
MODULE_AUTHOR("jihaixuan");
MODULE_DESCRIPTION("A simple in-memory filesystem");